package com.heima.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.admin.feign.ArticleFeign;
import com.heima.admin.feign.WemediaFeign;
import com.heima.admin.mapper.AdChannelMapper;
import com.heima.admin.mapper.AdSensitiveMapper;
import com.heima.admin.service.WemediaNewsAutoScanService;
import com.heima.common.aliyun.GreeTextScan;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.fastdfs.FastDFSClientUtil;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.article.pojos.ApAuthor;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.log4j.Log4j2;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.*;

@Service
@Log4j2
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {

    /**
     * 保存文章信息
     */
    @Autowired
    private ArticleFeign articleFeign;

    /**
     * 获取文章信息
     */
    @Autowired
    private WemediaFeign wemediaFeign;

    /**
     * 自媒体文章审核
     *
     * @param id
     */
    @Transactional
    @GlobalTransactional
    @Override
    public void autoScanByMediaNewsId(Integer id) {

        //参数校验
        if (null == id) {
            System.out.println("参数为空");
            return;
        }

        //根据id查询自媒体文章信息
        WmNews wmNews = wemediaFeign.findById(id);
        if (null == wmNews) {
            System.out.println("文章未查到");
            return;
        }

        //人工审核通过发布时间小于当前时间的直接保存数据
        if (wmNews.getPublishTime() != null && wmNews.getStatus() == 4 && wmNews.getPublishTime().getTime() <= new Date().getTime()) {
            saveAppArticle(wmNews);
            return;
        }

        //审核通过发布时间小于当前时间的直接保存数据
        if (wmNews.getPublishTime() != null && wmNews.getStatus() == 8 && wmNews.getPublishTime().getTime() <= new Date().getTime()) {
            saveAppArticle(wmNews);
            return;
        }

        //判断是否需要审核
        if (wmNews.getStatus() == WmNews.WM_COVER_REFERENCE) {

            //抽取文章信息中的图片和文本
            Map<String, Object> content = handleTextAndImages(wmNews);

            //调用阿里云文本反垃圾
            boolean textScanBoolean = handleTextScan((String) content.get("texts"), wmNews);
            if (!textScanBoolean) {
                return;
            }
//
//            //调用阿里云图片审核服务
//            boolean imagesScanBoolean = handleImagesScan((List<String>) content.get("images"), wmNews);
//            if (!imagesScanBoolean) {
//                return;
//            }

            //文章内容是否包含了自管理的敏感词
            boolean sensitiveScanBoolean = handleSensitive((String) content.get("texts"), wmNews);
            if (!sensitiveScanBoolean) {
                return;
            }
        }

        //审核通过发布时间大于当前时间 暂时不发布修改状态为8
        if (wmNews.getPublishTime() != null && wmNews.getPublishTime().getTime() >= new Date().getTime()) {
            wmNews.setStatus((short) 8);
            this.wemediaFeign.updateWmNews(wmNews);
            return;
        }

        //审核通过 保存app文章相关数据
        saveAppArticle(wmNews);
    }

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 保存app文章相关数据
     *
     * @param wmNews
     */
    private void saveAppArticle(WmNews wmNews) {

        //保存发布文章信息
        ApArticle apArticle = saveArticle(wmNews);

        //保存app文章配置
        saveArticleConfig(apArticle);

        //保存app文章内容
        saveArticleContent(apArticle, wmNews);

        //修改文章信息为审核通过
        wmNews.setStatus(WmNews.WM_FA_BU_REFERENCE);
        wmNews.setArticleId(apArticle.getId());
        wmNews.setPublishTime(new Date());
        wemediaFeign.updateWmNews(wmNews);

        //es索引创建
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", apArticle.getId());
        map.put("publishTime", apArticle.getPublishTime());
        map.put("layout", apArticle.getLayout());
        map.put("images", apArticle.getImages());
        map.put("authorId", apArticle.getAuthorId());
        map.put("title", apArticle.getTitle());
        IndexRequest indexRequest = new IndexRequest("app_info_article").id(apArticle.getId().toString()).source(map);
        try {
            restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 保存app文章内容
     *
     * @param apArticle
     * @param wmNews
     */
    private void saveArticleContent(ApArticle apArticle, WmNews wmNews) {

        ApArticleContent apArticleContent = new ApArticleContent();
        apArticleContent.setArticleId(apArticle.getId());
        apArticleContent.setContent(wmNews.getContent());

        articleFeign.saveArticleContent(apArticleContent);
    }

    /**
     * 保存app文章配置
     *
     * @param apArticle
     * @return
     */
    private void saveArticleConfig(ApArticle apArticle) {

        //创建对象 并获取参数
        ApArticleConfig apArticleConfig = new ApArticleConfig();
        apArticleConfig.setArticleId(apArticle.getId());
        apArticleConfig.setIsForward(true);
        apArticleConfig.setIsComment(true);
        apArticleConfig.setIsDown(false);
        apArticleConfig.setIsDelete(false);

        //保存数据
        articleFeign.saveArticleConfig(apArticleConfig);
    }

    @Autowired
    private AdChannelMapper adChannelMapper;

    /**
     * 保存发布文章信息
     *
     * @param wmNews
     * @return
     */
    private ApArticle saveArticle(WmNews wmNews) {

        //创建对象
        ApArticle apArticle = new ApArticle();

        //获取参数
        apArticle.setTitle(wmNews.getTitle());
        apArticle.setLayout(wmNews.getType());
        apArticle.setFlag((byte) 1);
        apArticle.setImages(wmNews.getImages());
        apArticle.setLabels(wmNews.getLabels());
        apArticle.setCreatedTime(wmNews.getCreatedTime());
        apArticle.setPublishTime(new Date());

        //获取发布者id和name
        WmUser wmUser = wemediaFeign.findWmUserById(Long.valueOf(wmNews.getUserId()));
        if (null != wmUser) {
            ApAuthor apAuthor = articleFeign.selectAuthorByName(wmUser.getName());
            if (null != apAuthor) {
                apArticle.setAuthorId(Long.valueOf(apAuthor.getId()));
                apArticle.setAuthorName(apAuthor.getName());
            }
        }

        //获取频道信息
        AdChannel adChannel = adChannelMapper.selectById(wmNews.getChannelId());
        if (null != adChannel) {
            apArticle.setChannelId(adChannel.getId());
            apArticle.setChannelName(adChannel.getName());
        }

        //保存发布文章信息 并返回
        return articleFeign.saveArticle(apArticle);
    }

    @Autowired
    private AdSensitiveMapper adSensitiveMapper;

    /**
     * 文章内容是否包含了自管理的敏感词
     *
     * @param texts
     * @param wmNews
     * @return
     */
    private boolean handleSensitive(String texts, WmNews wmNews) {

        //获取敏感词库
        List<String> allSensitive = adSensitiveMapper.findAllSensitive();

        //生成词典
        SensitiveWordUtil.initMap(allSensitive);

        //查询是否有敏感词
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(texts);

        if (stringIntegerMap.size() > 0) {

            //文本违规 审核失败
            wmNews.setStatus((short) 2);
            wmNews.setReason("文章中含有敏感词汇。");
            this.wemediaFeign.updateWmNews(wmNews);
            return false;
        }
        return true;
    }

    @Autowired
    private FastDFSClientUtil fastDFSClientUtil;

    @Autowired
    private GreenImageScan greenImageScan;

    @Value("${fdfs.url}")
    private String fdfsUrl;

    /**
     * 调用阿里云图片审核服务
     *
     * @param images
     * @param wmNews
     * @return
     */
    private boolean handleImagesScan(List<String> images, WmNews wmNews) {

        //判断是否有图 如果无图直接返回
        if (images.size() == 0) {
            return true;
        }

        List<byte[]> imageList = new ArrayList<>();

        try {
            //拆分图片路径
            for (String image : images) {
                String replace = image.replace(fdfsUrl, "");
                int index = replace.indexOf("/");
                String groupName = replace.substring(0, index);
                String path = replace.substring(index + 1);

                //下载图片
                byte[] download = fastDFSClientUtil.download(groupName, path);
                imageList.add(download);
            }

            //审核图片信息
            Map imageScan = greenImageScan.imageScan(imageList);

            //判断是否违规
            if (imageScan.get("suggestion").equals("pass")) {

                //图片无违规放行
                return true;
            } else if (imageScan.get("suggestion").equals("block")) {

                //图片违规 审核失败
                wmNews.setStatus((short) 2);
                wmNews.setReason("图片违规");
                this.wemediaFeign.updateWmNews(wmNews);
                return false;
            } else if (imageScan.get("suggestion").equals("review")) {

                //需要人工审核
                wmNews.setStatus((short) 3);
                wmNews.setReason("正在转移人工审核。");
                this.wemediaFeign.updateWmNews(wmNews);
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    @Autowired
    private GreeTextScan greeTextScan;

    /**
     * 调用阿里云文本反垃圾
     *
     * @param texts
     * @param wmNews
     * @return
     */
    private boolean handleTextScan(String texts, WmNews wmNews) {
        try {
            //调用接口经行校验
            Map textScan = greeTextScan.greeTextScan(texts);

            //判断是否违规
            if (textScan.get("suggestion").equals("pass")) {

                //文本无违规放行
                return true;
            } else if (textScan.get("suggestion").equals("block")) {

                //文本违规 审核失败
                wmNews.setStatus((short) 2);
                wmNews.setReason("文章中含有敏感词汇。");
                this.wemediaFeign.updateWmNews(wmNews);
                return false;
            } else if (textScan.get("suggestion").equals("review")) {

                //需要人工审核
                wmNews.setStatus((short) 3);
                wmNews.setReason("文章中可能含有敏感词汇，正在转移人工审核。");
                this.wemediaFeign.updateWmNews(wmNews);
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 抽取文章信息中的图片和文本
     *
     * @param wmNews
     * @return
     */
    private Map<String, Object> handleTextAndImages(WmNews wmNews) {

        //创建储存对象
        List<String> images = new ArrayList<>();
        String texts = "";

        //获取内容中的信息
        List<Map> list = JSON.parseObject(wmNews.getContent(), List.class);

        //分离文章中的图片和文本
        for (Map map : list) {
            if (map.get("type").equals("image")) {
                images.add((String) map.get("value"));
            } else {
                texts = texts + map.get("value") + ":";
            }
        }

        //添加封面图片
        if (null != wmNews.getImages() && null != wmNews.getType() && wmNews.getType() > 0) {
            String[] strings = wmNews.getImages().split(",");
            images.addAll(Arrays.asList(strings));
        }

        //添加 标题 标签
        texts = texts + wmNews.getTitle() + ":" + wmNews.getLabels();

        //储存数据 并响应
        Map<String, Object> maps = new HashMap<>();
        maps.put("images", images);
        maps.put("texts", texts);

        return maps;
    }
}
